package main

import (
	"encoding/json"
	"fmt"
	"html/template"
	"net/http"
	"os"

	"golang.org/x/net/websocket"
)

type MsgConfig struct {
	Type string `json:"type,omitempty"`
	Uid  string `json:"uid,omitempty"`
	Msg  string `json:"msg,omitempty"`
}

var connMap = make(map[string]*websocket.Conn)

func echo(ws *websocket.Conn) {
	var err error
	for {
		var reply string

		if err = websocket.Message.Receive(ws, &reply); err != nil {
			fmt.Println(err)
			continue
		}

		if err = websocket.Message.Send(ws, reply); err != nil {
			fmt.Println(err)
			continue
		}
	}
}

func sendMessage(replyMsg MsgConfig, conn *websocket.Conn, connUid string) {
	msg := "[" + replyMsg.Uid + "]:" + replyMsg.Msg
	if connUid == replyMsg.Uid {
		fmt.Println(msg)
		if replyMsg.Type == "login" {
			msg = "login success"
		} else {
			msg = "you say:" + replyMsg.Msg
		}

	}
	if err := websocket.Message.Send(conn, msg); err != nil {
		fmt.Println("can't send")
	}
}

func chat(ws *websocket.Conn) {
	var err error
	for {
		var reply string

		if err = websocket.Message.Receive(ws, &reply); err != nil {
			fmt.Println("can't receive")
			break
		}
		replyMsg := MsgConfig{}
		json.Unmarshal([]byte(reply), &replyMsg)

		if replyMsg.Type == "login" && replyMsg.Uid != "" {
			connMap[replyMsg.Uid] = ws
			fmt.Println(connMap)
		}
		for k, v := range connMap {
			go sendMessage(replyMsg, v, k)
		}
	}
}

func index(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		return
	}

	t, _ := template.ParseFiles("index.html")
	t.Execute(w, nil)
}

func main() {
	http.Handle("/echo", websocket.Handler(echo))
	http.Handle("/chat", websocket.Handler(chat))
	http.HandleFunc("/", index)

	if err := http.ListenAndServe("0.0.0.0:12345", nil); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
